#pragma once

#include <vector>
#include "BaseReader.h"
#include "IniData.h"
#include "LayoutList.h"

#define LAYOUT_INFO_INIFILE     TEXT("IniFile")
#define LAYOUT_INFO_APPEXECUTABLE TEXT("AppExecutable")
#define LAYOUT_INFO_APPWNDTITLE TEXT("AppWndTitle")
#define LAYOUT_INFO_APPWNDCLASS TEXT("AppWndClass")
#define LAYOUT_INFO_APPRESTART  TEXT("RestartOnChange")

#define LAYOUT_ITEM_TYPE        TEXT("Item")
#define LAYOUT_ITEM_NAME        TEXT("Name")
#define LAYOUT_ITEM_TAB         TEXT("Tab")

#define LAYOUT_ITEM_TYPE_TEXT       TEXT("Text")
#define LAYOUT_ITEM_TYPE_INT        TEXT("Int")
#define LAYOUT_ITEM_TYPE_CHECK      TEXT("Checkbox")
#define LAYOUT_ITEM_TYPE_INTLIST    TEXT("IntList")
#define LAYOUT_ITEM_TYPE_STRLIST    TEXT("StrList")
#define LAYOUT_ITEM_TYPE_FILELIST   TEXT("FileList")
#define LAYOUT_ITEM_TYPE_FILE       TEXT("File")
#define LAYOUT_ITEM_TYPE_FOLDER     TEXT("Folder")
#define LAYOUT_ITEM_TYPE_EMAILACC   TEXT("EmailAccount")
#define LAYOUT_ITEM_TYPE_COLOR      TEXT("Color")

class CLayoutInfo
{
public:
  CLayoutInfo() : appRestart(false)
  {}

  bool Load(CBaseReader& r);
  void Clear()
  {}

  CString  iniFile;
  CString  appExecutable;
  CString  appWndTitle;
  CString  appWndClass;
  bool     appRestart;
};

class CLayoutData
{
  struct SLayout
  {
    CString     tab;
    CLayoutList list;
  };
  typedef std::vector<SLayout*> CLayoutVector;

public:
  CLayoutData();
  ~CLayoutData();

  bool Load(const TCHAR* szLayoutFile);
  bool Save();

  CLayoutInfo& GetInfo()
  { return m_layoutInfo; }

  int  GetTabCount() const
  { return (int)m_layouts.size(); }

  int  GetTabIndex(const CString& name) const;

  CString GetTabName(int idx) const
  { if (idx >= 0 && idx < (int)m_layouts.size()) return m_layouts[idx]->tab; else return CString(TEXT("")); }
  CString GetTabName(CLayoutList* pList) const;

  bool BuildTabList(CList& list);

  CLayoutList* GetLayout(int tabIdx);

  bool IsChanged();
  
protected:
  void Clear();

  bool LoadLayout(CBaseReader& r);
  bool LoadIni(CBaseReader& r);

  bool LayoutToIni();
  bool IniToLayout();

  CLayoutListItem* CreateLayoutItem(const CString& type, const CString& name, const CString& tab);
  CLayoutList*     GetLayoutList(const CString& tab);

protected:
  CString       m_iniFile;
  bool          m_iniFileUtf8;
  CIniData      m_iniData;
  
  CLayoutInfo   m_layoutInfo;
  CLayoutVector m_layouts;
};
